package com.yejiali.backend.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yejiali.backend.common.apicode.ResponseCodeEnum;
import com.yejiali.backend.entity.Users;
import com.yejiali.backend.entity.dto.QrCodeDTO;
import com.yejiali.backend.entity.dto.UserDTO;
import com.yejiali.backend.entity.vo.WeChatUser;
import com.yejiali.backend.response.Response;
import com.yejiali.backend.service.UsersService;
import com.yejiali.backend.util.JwtUtil;
import com.yejiali.backend.util.RedisUtil;
import com.yejiali.backend.util.WeChatUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;


/**
 * @Author:yejiali
 * @Date:2025/7/15-07-15-11:09
 * @Decsription:com.yejiali.backend.controller
 * @Version:1.0
 */
@RestController
public class WxController {


    @Autowired
    private UsersService usersService;


    @Autowired
    private RedisUtil redisUtil;
    /**
     * 微信验证，内网穿透的域名验证
     */
    @GetMapping("/wxCheck")
    public String wxCheck(@RequestParam(value = "signature") String signature,
                          @RequestParam(value = "timestamp") String timestamp,
                          @RequestParam(value = "nonce") String nonce,
                          @RequestParam(value = "echostr") String echostr){
        System.out.println("微信验证请求"+signature+timestamp+nonce+echostr);
        return echostr;
    }

    /**
     * 生成二维码
     */
    @GetMapping(path = "/login" )
    public Response<QrCodeDTO> wxLoginPage(HttpServletRequest request,HttpServletResponse response) throws Exception {
        //重定向后的回调链接地址
        String redirect_uri= URLEncoder.encode("http://afe9c0b.r7.cpolar.top/wxCallback", StandardCharsets.UTF_8);
        //我将这里的state参数设置为二维码的唯一标识
        String state= UUID.randomUUID().toString();
        //设置二维码状态
        Map<String,Object> status=new HashMap<>();
        status.put("status","pending");
        //将state放入redis中，并设置过期时间
        redisUtil.hmset(state,status,100);
        //appId
        String appid="wx5036e8cb2f8f56b5";
        //构造二维码的链接地址
        String url= String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect",appid,redirect_uri,state);
        //String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid+"&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_userinfo&state="+state+"#wechat_redirect";
        //设置响应格式，生成二维码，直接写入输出响应流中
        String image64B = null;
        try {
            QrConfig qrConfig=new QrConfig(300,300);
            image64B = QrCodeUtil.generateAsBase64(url, qrConfig, "png");
        } catch (Exception e) {
            return Response.error(ResponseCodeEnum.INTERNAL_SERVER_ERROR.getCode(),"生成二维码失败");
        }
        //封装返回对象
        QrCodeDTO qrCodeDTO=new QrCodeDTO(state,image64B);
        System.out.println("生成二维码成功");
        return Response.success(qrCodeDTO);
    }

    /**
     * 验证二维码状态
     */
    @GetMapping("/checkState")
    public Response<Map<String,Object>> checkState(HttpServletResponse response, HttpServletRequest request,
                                  @RequestParam("state") String state){
        System.out.println(state);
        //查看二维码是否过期
        Map<Object, Object> status = redisUtil.hmget(state);
        //返回状态
        Map<String,Object> result=new HashMap<>();
        //二维码过期
        if (status.isEmpty()) {
            result.put("status","expired");
        }else {
            //返回二维码状态
            result.put("status", status.get("status"));
            System.out.println(status.get("status"));
            if (result.get("status").equals("confirmed")) {
                result.put("userInfo", status.get("userInfo"));
                result.put("token",status.get("token"));
            }
        }
        return Response.success(result);
    }


    @GetMapping(path= "/wxCallback")
    public void pcCallBack(HttpServletResponse response, HttpServletRequest request,
                                           @RequestParam("code") String code,
                                           @RequestParam("state") String state) throws IOException, InterruptedException {
        WeChatUser userInfo = WeChatUtil.getUserInfo(code);
        //根据openID去查询用户是否已注册
        QueryWrapper<Users> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("open_id",userInfo.getOpenid());
        Users user = usersService.getOne(queryWrapper);
        //TODO 这里在手机端也没有确认授权，默认这里授权之后再注册
        //若未注册，则对该用户进行注册
        if(user==null){
            user=usersService.register(userInfo);
        }
        //根据userId生成token
        Map<String,Object> tokenMap=new HashMap<>();
        tokenMap.put("userId",user.getUserId());
        //生成token
        String token = JwtUtil.genToken(tokenMap);
        //获取用户信息
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        //更新扫码状态
        Map<Object, Object> rawMap = redisUtil.hmget(state);
        // 转换为 Map<String, Object>
        Map<String, Object> status = new HashMap<>();
        if (!rawMap.isEmpty()) {
            for (Map.Entry<Object, Object> entry : rawMap.entrySet()) {
                status.put(entry.getKey().toString(), entry.getValue());
            }
        }
        if(!status.isEmpty()){
            status.put("status","confirmed");
            status.put("userInfo",userDTO);
            status.put("token",token);
        }
        //将用户信息存入redis中
        redisUtil.hmset(state,status);
        System.out.println(status);
    }

}
